package com.cshuig.patterns.proxy.dynamic;

import com.cshuig.patterns.proxy.dynamic.annotation.IntercepterMethod;
import com.cshuig.patterns.proxy.dynamic.interceptor.Interceptor;
import com.cshuig.patterns.proxy.dynamic.model.Invocation;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Objects;

/**
 * Created by hogan.lin on 2016/3/25.
 */
public class ProxyClass implements InvocationHandler {

    private Object target;

    // 添加拦截器, 将拦截逻辑封装到拦截器中，由客户端生成目标类的代理类的时候一起传入，这样客户端就可以设置不同的拦截逻辑
    private Interceptor interceptor;

    public ProxyClass(Object target, Interceptor interceptor) {
        this.target = target;
        this.interceptor = interceptor;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // System.out.println("业务规则写着这里太不好了，太死了");
        IntercepterMethod interceptMethod = interceptor.getClass().getAnnotation(IntercepterMethod.class);
        Objects.requireNonNull(interceptMethod);
        if (interceptMethod.value().equalsIgnoreCase(method.getName())) {
            return interceptor.interceptor(new Invocation(target, method, args));
        }
        return method.invoke(target, args);
    }

    /**
     * 动态代理的关键点：
     *      通过  Proxy.newProxyInstance  创建一个目标类的代理类
     *  拦截器作用： 将拦截逻辑封装到拦截器中，由客户端生成 目标类  代理类 的时候一起传入，这样客户端就可以设置不同的拦截逻辑， 灵活
     * @param target    目标类
     * @Param interceptor   目标类的拦截器
     * @return
     */
    public static Object bind(Object target, Interceptor interceptor) {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new ProxyClass(target, interceptor));
    }
}
